# curl --ssl --cacert `pwd`/certs/domain.crt https://dockeryezi.com/v2/_catalog

import requests
import time
import os

class Docker(object):

    def restart(self):
        # 执行arbage-collect命令，删除未被引用的layer
        os.system("docker exec `docker ps | grep registry | awk '{print $1}'` registry garbage-collect /etc/docker/registry/config.yml")
        # 重启registry容器
        os.system("docker restart `docker ps | grep registry | awk '{print $1}'`")

    def get_repos(self,hub):
        get_repos_url = '%s/v2/_catalog' % (hub)
        res = requests.get(get_repos_url, verify="../certs/domain.crt").json()
        return res['repositories']
        
    def __init__(self, hub):
        self.hub = hub

    @staticmethod
    def get_tag_list(hub, repo):
        # 获取这个repo的所有tags
        tag_list_url = '%s/v2/%s/tags/list' % (hub, repo)
        r1 = requests.get(url=tag_list_url, verify="../certs/domain.crt")
        tag_list = r1.json().get('tags')
        return tag_list

    def main(self):
        hub = self.hub
        repos = self.get_repos(hub=hub)
        for repo in repos:
            self.delete_images(hub=hub, repo=repo)
        self.restart()

    def is_valid_date(self,str):
      '''判断是否是一个有效的日期字符串'''
      try:
        if str.find("v") == 0:
            str = str.replace("v", "")
            if int(str) < 1200:
                return True
        # time.strptime(str, "%Y%m%d%H%M%S")
        return False
      except:
        return False
        """
        下面删除镜像的处理逻辑，可自定义编写
        我是根据时间戳作为镜像的标签，实现的思路是按照时间排序，保留最新的2个版本
        """
    def delete_images(self, hub, repo):
        tag_list = self.get_tag_list(hub=hub, repo=repo)
        # return
        if repo == "tarsupload/globalserver":
            print('开始处理 %s : %s' % (repo, tag_list))
        num = 0
        try:
            # 比如我所有服务的标签有三种：latest、SNAPSHOT、YYYYMMddHHmmss(时间戳)
            del_tag_list = []
            for tag in tag_list:
                # 标签是latest或者含有SNAPSHOT忽略删除
                if tag == 'latest' or 'SNAPSHOT' in tag or tag.find("v1.3.12") > -1 or tag.find(".") > -1 or repo != "tarsupload/globalserver" :
                    # print('%s 忽略 %s 删除' % (repo, tag))
                    a = 1
                elif self.is_valid_date(str=tag):
                    print('%s 符合时间戳标签' % (tag))
                    del_tag_list.append(tag)
            # 按照时间排序
            del_tag_list.sort()
            # 保存最新2个版本
            for item in del_tag_list[:-2]:
                print('%s 删除 %s' % (repo, item))
                # 获取image digest摘要信息
                get_info_url = '{}/v2/{}/manifests/{}'.format(hub, repo, item)
                header = {"Accept": "application/vnd.docker.distribution.manifest.v2+json"}
                r2 = requests.get(url=get_info_url, headers=header, timeout=10, verify="../certs/domain.crt")
                digest = r2.headers.get('Docker-Content-Digest')
                
                # 删除镜像
                delete_url = '%s/v2/%s/manifests/%s' % (hub, repo, digest)
                print("删除镜像地址：",delete_url)
                r3 = requests.delete(url=delete_url, verify="../certs/domain.crt")
                if r3.status_code == 202:
                    num += 1
        except Exception as e:
            # print(str(e))
            a = 2

        if repo == "tarsupload/globalserver":
            print('%s 共删除了%i个历史镜像' % (repo, num))
            print('------------------------------------------------------------')



if __name__ == '__main__':
    hub = 'https://dockeryezi.com'
    d = Docker(hub=hub)
    d.main()